home *** CD-ROM | disk | FTP | other *** search
- Path: nntp.irvine.com!adam
- From: adam@irvine.com (Adam Beneschan)
- Newsgroups: comp.lang.ada,comp.lang.c++
- Subject: Re: some questions re. Ada/GNAT from a C++/GCC user
- Date: 29 Mar 1996 23:52:59 GMT
- Organization: /z/news/newsctl/organization
- Message-ID: <4jht4r$tpo@krusty.irvine.com>
- References: <wnewmanDoxrCp.DKv@netcom.com> <315AC5E7.3A77@escmail.orl.mmc.com>
- NNTP-Posting-Host: calvin.irvine.com
-
- Ted Dennison <dennison@escmail.orl.mmc.com> writes:
-
- >> When I make two different instantiations of a generic package with the
- >> same arguments, I understand the compiler treats them formally as two
- >> different packages, which is OK with me. However, I'd appreciate
- >> knowing the compiler wouldn't actually output two redundant copies of
- >> the corresponding (identical?) machine code, but instead share the
- >> code. I saw somewhere that the compiler is given considerable freedom
- >> to share one instantiation between several arguments if it thinks it's
- >> appropriate, which is also OK with me. However, I haven't seen any
- >> guarantee that the compiler won't output redundant copies for
- >> instantiations with identical arguments. Is there such a guarantee?
- >
- >If you want a guarantee, put the code you want shared in a non-generic
- >package or procedure, and call it from your generic package or
- >procedure.
-
- I don't think this will always work, at least not cleanly. Suppose
- you have a generic whose only generic formal parameter is a private
- type:
-
- generic
- type T is private;
- package GENERIC_PACKAGE is
- ...
- procedure Do_Something (X : out T);
- procedure Do_Something_Else (X : in T);
- ...
- end GENERIC_PACKAGE;
-
- About the only thing the generic package body can do with objects of
- type T is to move them around. So, ignoring for the moment strange
- cases like unconstrained arrays, it should be easy for a compiler to
- generate one copy of Do_Something and Do_Something_Else (and similarly
- any procedure declared in the package body) for all instantiations of
- GENERIC_PACKAGE. Each procedure would take the size of T as an extra
- parameter, and whenever the procedure needs to move objects of type T
- around, it just does a raw byte copy, using the size parameter. This
- should run only slightly slower than if the compiler generated a
- separate copy of Do_Something for every instantiation, and each copy
- were able to treat the size as a known constant.
-
- But suppose you have a compiler that always generates a separate copy
- of all procedures for each instantiation. How would you write a
- non-generic shared procedure that you could call from the generic
- package?
-
- procedure Non_Generic_Do_Something (---well, what?)
-
- What types would the parameters of this routine be? The only
- possibilities I can see would be to have this routine take a
- SYSTEM.ADDRESS and a size parameter, or a byte array type, or some
- other low-level type. No matter how you do it, the code in
- GENERIC_PACKAGE, in order to call Non_Generic_Do_Something, would have
- to use UNCHECKED_CONVERSION or something like that (which doesn't fit
- my definition of "cleanly").
-
- Even if all you want is to make sure that only one copy of the code
- is generated when the generic parameters are identical, how can you do
- this by writing a shared non-generic routine? If, in four different
- places, you say:
-
- package GP1 is new GENERIC_PACKAGE (RECORD_TYPE_1);
-
- package GP2 is new GENERIC_PACKAGE (RECORD_TYPE_2);
-
- package GP3 is new GENERIC_PACKAGE (RECORD_TYPE_1);
-
- package GP4 is new GENERIC_PACKAGE (RECORD_TYPE_2);
-
- How could you write the Non_Generic_Do_Something routine, and the
- generic Do_Something procedure, so that just two versions of the
- Do_Something code (one to handle RECORD_TYPE_1 and one to handle
- RECORD_TYPE_2) are generated by the compiler?
-
- -- Adam
-